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
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
|
#include "rtconfig.h"
.text
.align 4
.section ".EL2_core_exceptions_table", "ax"
.globl EL2_core_exceptions_table
.type EL2_core_exceptions_table, %function
EL2_core_exceptions_table:
b EL2_Reset_Handler /* Reset Handler */
b EL2_Undefined_Handler /* Undefined Handler */
b EL2_HVC_Handler /* SVCall Handler */
b EL2_Prefetch_Handler /* Prefetch Handler */
b EL2_Abort_Handler /* Abort Handler */
b EL2_Trap_Handler /* Reserved */
b EL2_IRQ_Handler /* IRQ Handler */
b EL2_FIQ_Handler /* FIQ Handler */
.arm
.align 4
.section ".EL1_core_exceptions_table", "ax"
EL1_core_exceptions_table:
b EL1_Reset_Handler
b Undefined_Handler
b SVC_Handler
b Prefetch_Handler
b Abort_Handler
b Reserved_Handler
b IRQ_Handler
b FIQ_Handler
/* Reset Handler */
.text
.align 4
.section ".EL2_Reset_Handler", "ax"
.globl EL2_Reset_Handler
.type EL2_Reset_Handler, %function
EL2_Reset_Handler:
mov r0, #0
mov r1, r0
mov r2, r0
mov r3, r0
mov r4, r0
mov r5, r0
mov r6, r0
mov r7, r0
mov r8, r0
mov r9, r0
mov r10, r0
mov r11, r0
mov r12, r0
#ifdef RT_USING_FPU
mrc p15, #0x00, r2, c1, c0, #0x02
orr r2, r2, #0xF00000
mcr p15, #0x00, r2, c1, c0, #0x02
fmrx r2, fpexc
orr r2, r2, #0x40000000
fmxr fpexc, r2
#endif
ldr r0, =0x23000003
MCR p15, 0, r0, c15, c0, 0
/*---------------TCM Initialization-------------------*/
ldr r0, =0x0A000000 /* ATCM base address */
ldr r1, =0x00010000 /* TCM size: 64KB */
mov r2, #0 /* Clear value */
tcm_init_loop:
str r2, [r0], #4 /* Write and increment */
subs r1, r1, #4 /* Decrement counter */
bne tcm_init_loop /* Continue if not zero */
dsb /* Data synchronization barrier */
isb /* Instruction synchronization barrier */
b MPU_Init
MPU_Init:
mrc p15, 4, r0, c1, c0, 0 /* Read HSCTLR */
and r0, r0, #0xFFFFFFFE /* set HSCTLR.M bit to 0, disable EL2 MPU */
mcr p15, 4, r0, c1, c0, 0 /* write HSCTLR */
mrc p15, 0, r0, c1, c0, 0 /* Read SCTLR */
and r0, r0, #0xFFFFFFFE /* set SCTLR.M bit to 0, disable EL1 MPU */
mcr p15, 0, r0, c1, c0, 0 /* write SCTLR */
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #(0x1 << 12) /*icache */
orr r0, r0, #(0x1 << 2) /*dcache */
mcr p15, 0, r0, c1, c0, 0
disalbe_mpu_region_loop:
mov r0, r3 /* select region */
mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */
mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */
mrc p15, 4, r0, c6, c3, 1 /* Read From HPRLAR */
and r0, r0, #0xFFFFFFFE
mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */
mrc p15, 0, r0, c6, c3, 1 /* Read From PRLAR */
and r0, r0, #0xFFFFFFFE
mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */
add r3, r3, #1
cmp r3, #24 /* hsm has only 16 mpu regions */
blt disalbe_mpu_region_loop
/* region 0 cluster0/cluster1 tcm */
/* normal memory attribute */
ldr r0, =0 /* Region 0 */
mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */
mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */
ldr r0, =0x08000000 /* Start address */
orr r0, r0, #0x2 /* SH=0, AP=1, XN=0*/
mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */
mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */
ldr r0, =0x0AFFFFFF /* End address */
and r0, r0, #0xFFFFFFC0
orr r0, r0, #0x3 /* AttrIndex=1, non-cacheable, enable region */
mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */
mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */
/*---------------region 1 mcu sram (uncacheable)---------------*/
/* normal memory attribute */
ldr r0, =1 /* Region 1 */
mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */
mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */
ldr r0, =0x0C800000 /* Start address */
orr r0, r0, #0x2 /* SH=0, AP=1, XN=0*/
mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */
mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */
ldr r0, =0x0CAAFFFF /* End address */
and r0, r0, #0xFFFFFFC0
orr r0, r0, #0x3 /* AttrIndex=1, non-cacheable, enable region */
mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */
mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */
/*---------------region 2 image read-only (cacheable, executable)---------------*/
/* 0x0CAB0000 ~ (__image_rw_start__ - 64), startup/text/rodata */
ldr r0, =2 /* Region 2 */
mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */
mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */
ldr r0, =0x0CAB0000 /* Start: FLASH_STARTUP (64-byte aligned) */
orr r0, r0, #0x6 /* SH=0, AP=3, XN=0 */
mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */
mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */
ldr r0, =__image_rw_start__ /* End address: __image_rw_start__ is 64-byte aligned */
sub r0, r0, #0x40 /* Limit = __image_rw_start__ - 64 */
orr r0, r0, #0x1 /* AttrIndex=0, cacheable, enable region */
mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */
mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */
/*---------------region 4 image read-write (cacheable, XN)----------------*/
ldr r0, =4 /* Region 4 */
mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */
mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */
ldr r0, =__image_rw_start__ /* __image_rw_start__ is 64-byte aligned */
and r0, r0, #0xFFFFFFC0 /* Ensure 64-byte alignment */
orr r0, r0, #0x12 /* SH=0, AP=1, XN=1 */
mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */
mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */
ldr r0, =__image_rw_end__ /* End address: __image_rw_end__ is 64-byte aligned */
sub r0, r0, #0x40 /* Limit = __image_rw_end__ - 64 */
orr r0, r0, #0x1 /* AttrIndex=0, cacheable, enable region */
mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */
mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */
/* Keep __image_rw_end__ ~ OS_HEAP_START_ADDR unmapped as a guard gap. */
/*---------------region 5 RTOS heap (cacheable, XN)----------------*/
ldr r0, =5 /* Region 5 */
mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */
mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */
ldr r0, =OS_HEAP_START_ADDR /* OS_HEAP_START_ADDR is 64-byte aligned */
and r0, r0, #0xFFFFFFC0 /* Ensure 64-byte alignment */
orr r0, r0, #0x12 /* SH=0, AP=1, XN=1 */
mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */
mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */
ldr r0, =OS_HEAP_END_ADDR /* End address: OS_HEAP_END_ADDR is 64-byte aligned */
sub r0, r0, #0x40 /* Limit = OS_HEAP_END_ADDR - 64 */
orr r0, r0, #0x1 /* AttrIndex=0, cacheable, enable region */
mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */
mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */
/*---------------region 11 shared/reserved SRAM (non-cacheable, XN)----------------*/
ldr r0, =11 /* Region 11 */
mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */
mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */
ldr r0, =OS_HEAP_END_ADDR /* OS_HEAP_END_ADDR is 64-byte aligned */
and r0, r0, #0xFFFFFFC0 /* Ensure 64-byte alignment */
orr r0, r0, #0x12 /* SH=0, AP=1, XN=1 */
mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */
mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */
ldr r0, =0x0CDFFFFF /* End address */
and r0, r0, #0xFFFFFFC0
orr r0, r0, #0x3 /* AttrIndex=1, non-cacheable, enable region */
mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */
mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */
/*---------------region 6 internal gic & peripheral---------------*/
/* device memory attribute */
ldr r0, =6 /* Region 6 */
mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */
mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */
ldr r0, =0x22000000 /* Start address */
orr r0, r0, #0x13 /* SH=2, AP=1, XN=1*/
mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */
mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */
ldr r0, =0x223FFFFF /* End address */
sub r0, r0, #1
and r0, r0, #0xFFFFFFC0
orr r0, r0, #0x7 /* AttrIndex=3, device memory, enable region */
mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */
mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */
/*---------------region 7 peripheral---------------*/
/* device memory attribute */
ldr r0, =7 /* Region 7 */
mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */
mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */
ldr r0, =0x23000000 /* Start address */
orr r0, r0, #0x13 /* SH=2, AP=1, XN=1*/
mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */
mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */
ldr r0, =0x2FFFFFFF /* End address */
sub r0, r0, #1
and r0, r0, #0xFFFFFFC0
orr r0, r0, #0x7 /* AttrIndex=3, device memory, enable region */
mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */
mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */
/*---------------region 8 CPUSYS------------------*/
ldr r0, =8 /* Region 8 */
mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */
mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */
ldr r0, =0x30000000 /* Start address */
orr r0, r0, #0x13 /* SH=2, AP=1, XN=1*/
mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */
mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */
ldr r0, =0x3FFFFFFF /* End address */
and r0, r0, #0xFFFFFFC0
orr r0, r0, #0x7 /* AttrIndex=3, device memory, enable region */
mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */
mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */
/*---------------region 9 DDR-------------------*/
ldr r0, =9 /* Region 9 */
mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */
mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */
ldr r0, =0x80000000 /* Start address */
orr r0, r0, #0x2 /* SH=0, AP=1, XN=0*/
mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */
mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */
ldr r0, =0xFFFFFFFF /* End address */
and r0, r0, #0xFFFFFFC0
orr r0, r0, #0x3 /* AttrIndex=1, enable region */
mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */
mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */
/*---------------region 10 xspi-------------------*/
/* device memory attribute */
ldr r0, =10 /* Region 10 */
mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */
mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */
ldr r0, =0x18000000 /* Start address */
orr r0, r0, #0x13 /* SH=2, AP=1, XN=1*/
mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */
mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */
ldr r0, =0x1FFFFFFF /* End address */
and r0, r0, #0xFFFFFFC0
orr r0, r0, #0x7 /* AttrIndex=3, device memory, enable region */
mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */
mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */
/*---------------SET MAIR/HMAIR-------------------*/
ldr r0, =0x44FF /* attr0(FF): normal memory, write-back non-transient */
/* attr1(44): normal memory, non-cacheable */
/* attr2~3(00): Device-nGnRnE memory */
mcr p15, 4, r0, c10, c2, 0 /* Write HMAIR0 */
mcr p15, 0, r0, c10, c2, 0 /* Write MAIR0 */
ldr r0, =0x04 /* attr4~7(04/00): Device-nGnRnE memory */
mcr p15, 4, r0, c10, c2, 1 /* Write HMAIR1 */
mcr p15, 0, r0, c10, c2, 1 /* Write MAIR1 */
mpu_enable:
mrc p15, 4, r0, c1, c0, 0 /* Read HSCTLR */
orr r0, r0, #0x1 /* Enable MPU */
dsb
mcr p15, 4, r0, c1, c0, 0 /* Write HSCTLR */
isb
mrc p15, 0, r0, c1, c0, 0 /* Read SCTLR */
orr r0, r0, #0x1 /* Enable MPU */
dsb
mcr p15, 0, r0, c1, c0, 0 /* Write SCTLR */
isb
/* ARMv8-R cores are in EL2 (hypervisor mode) after reset, and we need
to descend to EL1 (supervisor mode) or EL0 (user mode) */
/* Init HVBAR (Hypervisor Vector Base Address Register) */
ldr r0, =EL2_core_exceptions_table
mcr p15, 4, r0, c12, c0, 0 /* Move to Coprocessor from ARM Register */
/* Init VBAR (Vector Base Address Register) */
ldr r0, =EL1_core_exceptions_table
mcr p15, 0, r0, c12, c0, 0 /* Move to Coprocessor from ARM Register */
init_mcu_stack:
ldr r3, =__StackTop
mov SP, r3
bl init_bss
/* Init ELR_hyp with EL1_Reset_Handler so eret can descend from EL2 to EL1. */
ldr r0, =EL1_Reset_Handler
msr ELR_hyp, r0
mrs r0, SPSR_hyp
and r0, r0, #~0x00FF /* r0 = r0 & FFFF FFE0. Clear SPSR_hyp bits [4:0] -> Execution state bit + Mode bits. */
/* Return to EL1 system mode with interrupts masked until EL1 stack setup is done. */
orr r0, r0, #0x1f
bic r0, r0, #(0x1 << 5)
msr SPSR_hyp, r0
/* Configure the GIC CPU Interface */
/* Disable group 0 interrupts */
mov r0, #0x00
mcr p15, 0, r0, c12, c12, 6 /* Write to ICC_IGRPEN0 */
/* Enable group 1 interrupts */
mov r0, #0x01
mcr p15, 0, r0, c12, c12, 7 /* Write to ICC_IGRPEN1 */
/* Set the interrupt priority mask to biggest value - 0x1F */
/* Interrupts with all priorities are allowed. */
mov r0, #0xF8 /* The priority bitfield is shifted with 3 bits - 0x1F becomes 0xF8 */
mcr p15, 0, r0, c4, c6, 0 /* Write to ICC_PMR */
/* Set the binary point for group 0 and group 1 interrupts */
mov r0, #0
mcr p15, 0, r0, c12, c8, 3 /* Write to ICC_BPR0 */
mcr p15, 0, r0, c12, c12, 3 /* Write to ICC_BPR1 */
/* Exception return - will jump to address pointed by ELR_hyp (main) */
eret /* When executed in Hyp mode, ERET loads the PC from ELR_hyp and loads the CPSR from SPSR_hyp */
.text
.align 4
.globl EL1_Reset_Handler
.type EL1_Reset_Handler, %function
EL1_Reset_Handler:
/* Divide the non-USR mode stack area between the 5 non-USR modes */
/* ABT,UND get 1/10 each. HYP, SVC,FIQ,IRQ get 1/5 each. */
ldr r3, =__StackTop
ldr r2, =__StackLimit
sub r2, r3, r2 /* r2 : size in bytes */
mov r4, #2
udiv r1, r2, r4 /* r1 : size divided by 2 */
and r1, r1, #~0x0f /* r1 size alligned to 16 bytes */
/* Setup the stack for supervisor mode (entered from reset) */
mrs r0, cpsr
and r0, r0, #~0x00FF
orr r0, r0, #0x0033
msr cpsr_c, r0
sub r3, r3, r1
mov SP, r3 /* top of stack to SP_svc */
ldr r3, =__StackTop_exc
ldr r2, =__StackLimit_exc
sub r2, r3, r2 /* r2 : size in bytes */
mov r4, #4
udiv r1, r2, r4 /* r1 : size divided by 4 */
and r1, r1, #~0x0f /* r1 size alligned to 16 bytes */
/* Go to FIQ mode and set stack (below the previous one) */
mrs r0, cpsr
and r0, r0, #~0x003F
orr r0, r0, #0x0031
msr cpsr_c, r0
sub r3, r3, r1
mov SP, r3
/* Go to IRQ mode and set stack (below the previous one) */
mrs r0, cpsr
and r0, r0, #~0x003F
orr r0, r0, #0x0032
msr cpsr_c, r0
sub r3, r3, r1
mov SP, r3
/* Go to ABORT mode and set stack (below the previous one) */
mrs r0, cpsr
and r0, r0, #~0x003F
orr r0, r0, #0x0037
msr cpsr_c, r0
sub r3, r3, r1
mov SP, r3
/* Go to UNDEF mode and set stack (below the previous one) */
mrs r0, cpsr
and r0, r0, #~0x003F
orr r0, r0, #0x003b
msr cpsr_c, r0
sub r3, r3, r1
mov SP, r3
/* Go to SYSTEM mode and set stack to the top of the reserved area */
/* This is also the stack for user mode */
mrs r0, cpsr
and r0, r0, #~0x003F
orr r0, r0, #0x003F
msr cpsr_c, r0
ldr r3, =__StackTop_exc
mov SP, r3
/* Enable IRQ and FIQ interrupts for the system/user mode */
cpsie i /* Unmask interrupts (IRQ)*/
cpsie f /* Unmask fast interrupts (FIQ)*/
/* Go to supervisor mode */
mrs r0, cpsr
and r0, r0, #~0x00FF
orr r0, r0, #0x0033
msr cpsr_c, r0
/* Jump to the entry() method */
bl entry
/* Should never get here */
b .
.text
.align 4
.globl init_bss
.type init_bss, %function
init_bss:
ldr r1, =__bss_start
ldr r2, =__bss_end
mov r0, #0
.clear_bss_loop:
cmp r1, r2
bcs .init_done
str r0, [r1], #4
b .clear_bss_loop
.init_done:
bx lr
|